El JNDI es un API definido independientemente de cualquier implementaci�n de nombrado espec�fico o servico de directorio. Para que una aplicaci�n, un applet, o una unidad de programa puedan usar JNDI, deben especificar el proveedor de servicios a usar y deben tener acceso a los ficheros class del proveedor. Un s�lo programa podr�a usar m�s de un proveedor. Adem�s, el programa y/o los proveedores podr�an usar facotr�as de objetos, factor�as de clases, y factor�as de control, cuyos ficheros class tambi�n deben estar disponibles para el JNDI. Adem�s, el JNDI necesita acceder a los ficheros de recursos de aplicaci�n (ver la secci�n Ficheros de Recursos de Aplicaci�n) proporcionados por el programa, los proveedores y otros componentes. En todos estos casos, el JNDI necesita cargar clases y ficheros de recursos. Esta secci�n explica c�mo el JNDI usa los cargadores de clases y c�mo nos puede afectar su utilizaci�n.
�Cargadores de Clases en Segundo Plano
La carga de clases significa que las clases Java y los recursos se cargan dentro del JRE (Java Runtime Environment). Controla un rango de distintas pol�ticas como desde d�nde cargar las definiciones de clases hasta el formato de los datos de las definiciones de clases.
En versiones anteriores del JDK 1.1, no exist�a relaci�n entre distintos cargadores de clases, Un cargador de clases del sistema es responable de cagar en el JRE, la aplicaci�n y las clases y recursos en el classpath de la aplicaci�n. Un cargador de clases de applet es resposnable de cargar los applets y sus recursos relacionados, posiblemente a trav�s de la red comunic�ndose con un servidor Web.
En la Java 2 Platform, Standard Edition, v1.2 y versiones posteriores, los cargadores de clases tienen una relaci�n jer�rquica. Cada cargador de clase tiene un cargador de clases padre. Cuando se le pide a un cargador de clases que cargue una clase o un recurso, consulta con su cargador de clases padre antes de intentar cargar el �tem el mismo. El padre, a su vez consulta a su padre, etc. Por esto es s�lo si despu�s de todos los cargadores de clases ancestros no pueden encontrar el �tem que el cargador de clases actual obtiene.
Un cargador de clases bootstrap es el responsable de cargar el JRE. Es la "r�iz" del �rbol de cargadores de clases. El cargador de clases del sistema es un descendiente del cargador de clases bootstrap.
Es el responsable de cargar la aplicaci�n, as� como las clases y recursos en el classpath de la aplicaci�n.
La plataforma Java 2 tambi�n presenta la noci�n de cargador de clases de contexto. Un cargador de clases de contexto de threads esta, por defecto, configurado como el cargador de clases de contexto de los padres del thread. La jerarqu�a de threads esta enraizada en el thread primordial (el que ejecuta el programa). El cargador de clases de contexto del thread primordial es configurado como el cargador de clases que carg� la aplicaci�n. Por eso amenos que cambiemos expl�citamente el cargador de clases de contexto del thread, su cargador de clases de contexto ser� el mismo que el de la aplicaci�n. Es decir, el cargador de clases de contexto puede cargar las clases que pueda cargar la aplicaci�n. Este cargador lo usa el JRE como el RMI (Java Remote Method Invocation) para cargar clases y recursos en beneficio del usuario de la aplicaci�n. El cargador de clases de contexto, como el cargador de la plataforma Java 2, tiene un cargador de clases padre y soporta el mismo modelo de delegaci�n para la carga de clases descrito anteriormente.
�Cargar Clases con el Software JDK 1.1
Cuando usamos el JNDI con el JDK 1.1, debemos situar los ficheros JARs del proveedor de servicios y los ficheros JARs o los ficheros class que contienen las factor�as en el classpath de la aplicaci�n. Si estamos usando un applet, debemos situar dichos ficheros en el directorio codebase del applet y/o en las localizaciones de los archivos. Consecuentemente, el cargador de clases que carga los JARs del JNDI normalmente es el mismo que carga la aplicaci�n y las factor�as.
Observa que no podemos usar los ficheros de recursos de apliaci�n JNDI con el JDK 1.1. Puedes ver la secci�n Ficheros de Recurso de Aplicaci�n para m�s detalles.
�Cargar Clases en la Plataforma Java 2
Cuando usamos el JNDI con la plataforma Java 2, el cargador de clases que carga las clases JNDI normalmente es diferente del que carga la aplicaci�n, Por ejemplo, en el Java 2 SDK, v1.3, las clases JNDI las carga el cargador de clases bootstrap mientras que las clases de la aplicaci�n las carga el cargador de clases del sistema. En el Java 2 SDK, v1.2, si instalamos el JNDI como una extensi�n instalada, las clases JNDI las carga el cargador de clases responsable de cargar las extensiones instaladas, mientras que las clases de la aplicaci�n las carga el cargador de clases del sistema. Como resultado, si el JNDI usa su cargador de clases para cargar los proveedores de servicio y las factor�as, podr�a no ver las mismas clases que la aplicaci�n. Por lo tanto, para intentar ver lo mismo que la aplicaci�n puede ver, el JNDI usa el cargador de clases de contexto del thread llamante cuando est� cargando las clases para los proveedores de servicios, las factor�as y los ficheros de recursos de aplicaci�n.
En raras circunstancias, querremos cambiar el cargador de clases del contexto del thread para que afecte al modo de encontrar las clases JNDI. Esto podr�a ocurrir, por ejemplo, cuando el entorno en el que estamos trabajando no ve apropiadamente el cargador de clases de contexto. Por ejemplo, un bug en el Java 2 SDK, Standard Edition, v1.2.2 hace que el AWT (Abstract Window Toolkit) no configure los oyentes del cargador de clases de contexto del thread para qu sea el cargador de clases que carga el applet. Consecuentemente, lo m�todos de retrollamada invocados por los threads oyentes no tienen acceso al proveedor de servicios ni a las factor�as que el applet por otro lado puede cargar expl�citamente. O, podr�amos querer a�adir un repositorio adicional de fichero JAR o class que contenga proveedores o factor�as especiales para nuestras aplicaciones o applets. Para cambiar el cargador de clases de contexto del thread, usamos Thread.setContextClassLoader().
Aqu� tenemos un ejemplo.
ClassLoader prevCl = Thread.currentThread().getContextClassLoader();
// Create the class loader by using the given URL
// Use prevCl as parent to maintain current visibility
ClassLoader urlCl =
URLClassLoader.newInstance(new URL[]{new URL(url)}, prevCl);
try {
// Save the class loader so that you can restore it later
Thread.currentThread().setContextClassLoader(urlCl);
// Expect that the environment properties are in the
// application resource file found at "url"
Context ctx = new InitialContext();
System.out.println(ctx.lookup("tutorial/report.txt"));
// Do something useful with ctx
...
} catch (NamingException e) {
// Handle the exception
} finally {
// Restore
Thread.currentThread().setContextClassLoader(prevCl);
}
Este ejemplo crea un URLClassLoader que carga clases desde una URL espec�ficada. Luego crea un contexto inicial y realiza otras operacioens JNDI dentro del contexto de ese cargador de clases. En este ejemplo, el cargador de clases s�lo afecta al modo de inicializaci�n del contexto inicial (mediante un fichero de recursos de aplicaci�n encontrado por el nuevo cargador de clases), as� como en el resultado de lookup() (mediante la factor�a de objetos nombrada en el fichero de recursos de aplicaci�n y el fichero class de la factor�a encontrado por el nuevo cargador de clases. Para ejecutar este programa, debemos suministrar la URL codebase de esta forma.
# java ChangeClassLoader file:/some/directory/somewhere/
En este codebase, podemos especificar un fichero jndi.properties.
En este ejemplo particular, este es el fichero jndi.properties en el directorio del codebase.
java.naming.factory.initial=com.sun.jndi.fscontext.FSContextFactory java.naming.provider.url=file:/tmp java.naming.factory.object=FooObjectFactory
En el mismo directorio codebase est� la definici�n de la clase para FooObjectFactory, que cuando se el da un objeto java.io.File siempre devuelve el string "foo". Cuando ejecutamos este programa, veremos esta salida.
foo
Si no vemos esta salida, debemos chequear la correcci�n del argumento URL.
Debemos recordar que si estamos nombrando un directorio codebase, debemos incluir una barra inclinada al final de la URL.
�Cargar Clases desde Localizaciones Pre-Especificadas
En algunos casos, la localizaci�n de los ficheros class se especifica expl�citamente. Por ejemplo, podemos especificar el codebase para una factor�a de objetos en su Reference.
Cuando el JNDI lea dicho objeto desde el servicio de nombres o de directorio, usar� un cargador de clases para el codebase nombrado en la Reference para obtener los ficheros class de la factor�a. El padre de este cargador de clases es el cargador de clases de contexto del thread.